/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Simulator;

/**
 * The Stack class holds the global variables of the three stacks in the machine.  This class will manipulate the stacks based on the calls 
 * from other modules.
 * @author khhill
 */
public class Stack {
    public static String[] status_stack = new String[10];
    public static int[] test_stack = new int[32];
    public static int[] data_stack = new int[512];
    public static int data_stack_size = 0;
    public static int test_stack_size = 0;
    public static int status_stack_size = 0;
    
    
    
        /**
    * The PushData instruction will push data onto the current data stack.
    * <p>
    * <b>Change Log:</b><br>
    * None<br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * 168: Stack at capacity <br>
    * <p>
    * <b>Date of module being installed:</b> 5/19/08
    * <p><b>Original Author:</b>  Keith Hill
    * @param data This is the data that will end up on the statck.
    * @return The function will either return a 1 or 2000.  It will return a 1 if it was completed successfully and 2000 if it was not.
    */
    public static int PushData(int data){
        if(data_stack_size == 512){
            System.out.println("Error 168:  Stack at capacity.  Push not performed.");
            return 2000;
        }
        int counter = data_stack_size-1;
        while(counter>0){
            data_stack[counter] = data_stack[counter-1];
            counter --;
        }
        data_stack[0] = data;
        
        data_stack_size++;
        return 1;
    }
    
            /**
    * The PushStatus instruction will push data onto the current status stack.  Since the 
             * status stack is more forgiving than the data stack, there is no test to determine if the 
             * status stack is at capacity.  If it is, we simply replace the old value at the largest index and don't 
             * increase the stack size.
    * <p>
    * <b>Change Log:</b><br>
    * None<br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * None <br>
    * <p>
    * <b>Date of module being installed:</b> 5/19/08
    * <p><b>Original Author:</b>  Keith Hill
    * @param data This is the data that will end up on the statck.
    */
    public static void PushStatus(String data){
        
        int counter = status_stack_size-1;
        while(counter>0){
            status_stack[counter] = status_stack[counter-1];
            counter --;
        }
        status_stack[0] = data;
        
        if(status_stack_size<10){
            status_stack_size++;
        }
    }
    
            /**
    * The PushTest instruction will push data onto the current test stack.  The test stack does not produce an error 
             * if the stack has reached capacity.  If it has, it will remove the oldest data.
    * <p>
    * <b>Change Log:</b><br>
    * None<br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * <p>
    * <b>Date of module being installed:</b> 5/19/08
    * <p><b>Original Author:</b>  Keith Hill
    * @param data This is the data that will end up on the statck.
    */
    public static void PushTest(int data){
                
        int counter = test_stack_size-1;
        while(counter>0){
            test_stack[counter] = test_stack[counter-1];
            counter --;
        }
        test_stack[0] = data;
        
        if(test_stack_size<10){
            test_stack_size++;
        }
    }
    
    
            /**
    * The PopData instruction will pop the data from the top of the stack and return it to the caller.
    * <p>
    * <b>Change Log:</b><br>
    * None<br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * 213: Pop performed when stack is empty. <br>
    * <p>
    * <b>Date of module being installed:</b> 5/19/08
    * <p><b>Original Author:</b>  Keith Hill
    * @return The function will return the item at the top of the data stack.  If the stack is empty, it will return 0.
    */
    public static int PopData(){
        if(data_stack_size == 0){
            System.out.println("Error 213:  Pop performed when stack is empty.  0 was returned.");
            return 0;
        }
        int value = data_stack[0];
        int counter = 0;
        while(counter<data_stack_size){
            data_stack[counter] = data_stack[counter+1];
            counter ++;
        }
        
        data_stack_size--;
        return value;
    }
    
    
            /**
    * The PopStatus instruction will pop the data from the top of the stack and return it to the caller.
    * <p>
    * <b>Change Log:</b><br>
    * None<br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * 213: Pop performed when stack is empty. <br>
    * <p>
    * <b>Date of module being installed:</b> 5/19/08
    * <p><b>Original Author:</b>  Keith Hill
    * @return The function will return the item at the top of the status stack.  If the stack is empty, it will return 0.
    */
    public static String PopStatus(){
        if(status_stack_size == 0){
            System.out.println("Error 213:  Pop performed when stack is empty.  0 was returned.");
            return "0000";
        }
        String value = status_stack[0];
        int counter = 0;
        while(counter<status_stack_size){
            status_stack[counter] = status_stack[counter+1];
            counter ++;
        }
        
        status_stack_size--;
        return value;
    }
    
            /**
    * The PopTest instruction will pop the data from the top of the stack and return it to the caller.
    * <p>
    * <b>Change Log:</b><br>
    * None<br>
    * <p>
    * <b>Error Conditions Tested:</b><br>
    * 213: Pop performed when stack is empty. <br>
    * <p>
    * <b>Date of module being installed:</b> 5/19/08
    * <p><b>Original Author:</b>  Keith Hill
    * @return The function will return the item at the top of the test stack.  If the stack is empty, it will return 0.
    */
    public static int PopTest(){
        if(test_stack_size == 0){
            System.out.println("Error 213:  Pop performed when stack is empty.  0 was returned.");
            return 0;
        }
        int value = test_stack[0];
        int counter = 0;
        while(counter<test_stack_size){
            test_stack[counter] = test_stack[counter+1];
            counter ++;
        }
        
        test_stack_size--;
        return value;
    }
    

    
    public void PrintDataStack(){
        for(int i=0;i<data_stack_size; i++){
            String stack_output = "DATASTACK("+i+")= "+data_stack[i];
            System.out.println(stack_output);
        }
    }
    
    public void PrintStatusStack(){
        for(int i=0;i<status_stack_size; i++){
            String stack_output = "STATUSSTACK("+i+")= "+status_stack[i];
            System.out.println(stack_output);
        }
    }
    
    public void PrintTestStack(){
        for(int i=0;i<test_stack_size; i++){
            String stack_output = "TESTSTACK("+i+")= "+test_stack[i];
            System.out.println(stack_output);
        }
    }
}
